package com.gmrz.uas.plugin.idauth;

import com.gmrz.uas.plugin.authservice.AuthServiceConfigSpec;
import com.gmrz.uas.plugin.authservice.AuthServiceData;
import com.gmrz.uas.plugin.authservice.AuthServiceDataSpec;
import com.gmrz.uas.plugin.authservice.BaseAuthServicePlugin;
import com.gmrz.uas.plugin.authservice.exception.AuthenticationException;
import com.gmrz.uas.plugin.exception.PluginException;
import com.gmrz.uas.plugin.util.HttpClientUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by gongyuqiang on 2017/5/14.
 */
public class IDFaceAuthService extends BaseAuthServicePlugin {
    private static final Logger LOG = LogManager.getLogger(IDFaceAuthService.class);

    public static final String CONFIG_KEY_APPKEY = "appKey";
    public static final String CONFIG_KEY_SECRET = "appSecret";
    public static final String CONFIG_KEY_SERVER_HOST = "host";
    public static final String CONFIG_KEY_SERVER_PORT = "port";
    public static final String CONFIG_KEY_CONFIDENCE = "confidence";

    public static final String CONTENT_ID_PHOTO = "photo";


    public IDFaceAuthService(){
        this.allConfig = new HashMap<String, String>();

        this.allConfigSpec = new HashMap<String, AuthServiceConfigSpec>();
        this.allConfigSpec.put(CONFIG_KEY_APPKEY, new AuthServiceConfigSpec("", ""));
        this.allConfigSpec.put(CONFIG_KEY_SECRET, new AuthServiceConfigSpec("", ""));
        this.allConfigSpec.put(CONFIG_KEY_SERVER_PORT, new AuthServiceConfigSpec("", ""));
        this.allConfigSpec.put(CONFIG_KEY_SERVER_HOST, new AuthServiceConfigSpec("", ""));
        this.allConfigSpec.put(CONFIG_KEY_CONFIDENCE, new AuthServiceConfigSpec("", ""));

        this.allDataSpec = new HashMap<String, AuthServiceDataSpec>();
        this.allDataSpec.put(CONTENT_ID_PHOTO, new AuthServiceDataSpec().withSupprotPersistent(true));

    }
    private String signData(String appKey, String appSecret, String cardno, String name, String clienttime, String transactionno){

        StringBuilder builder = new StringBuilder();
        builder.append(appSecret);
        builder.append(appKey);
        builder.append(cardno);
        builder.append(clienttime);
        builder.append(name);
        builder.append(transactionno);
        builder.append(appSecret);

        return CryptoUtil.getMD5Digest(builder.toString());

    }

    protected static Map<String, Object> StringtoMap(String str) {

        GsonBuilder gb = new GsonBuilder();
        Gson gson = gb.create();
        return gson.fromJson(str, new TypeToken<Map<String,Object>>(){}.getType());
    }

    /**
     * 人脸实名认证
     * @param userId
     * @param contents
     * @throws PluginException
     */
    public void authenticate(String userId, List<AuthServiceData> contents) throws PluginException {
        if(contents == null){
            throw new AuthenticationException("invalid params for idface authentication");
        }

        String appKey = this.allConfig.get(CONFIG_KEY_APPKEY);
        String appSecret = this.allConfig.get(CONFIG_KEY_SECRET);
        String host = this.allConfig.get(CONFIG_KEY_SERVER_HOST);
        String port = this.allConfig.get(CONFIG_KEY_SERVER_PORT);
        int confidence = Integer.parseInt(this.allConfig.get(CONFIG_KEY_CONFIDENCE));

        //appKey ="36d8bae1844845e5b60f0d7f366671bd";
        //appSecret = "JMipcXBhK6bOnrHWF97M1XZt";

        //host = "192.168.6.134";
        //port = "7501";


        String name = "";
        String cardno = "";
        String photo = "";

        String startTime = "";
        String endTime = "";

        String logname = "";
        String logcardno = "";
        String logphoto = "";

        String logstartTime = "";
        String logendTime = "";

        startTime = new sun.misc.BASE64Encoder().encode(CryptoUtil.encrypt3DES(startTime.getBytes(), appSecret)) ;
        endTime = new sun.misc.BASE64Encoder().encode(CryptoUtil.encrypt3DES(endTime.getBytes(), appSecret)) ;
        for(AuthServiceData content : contents){

            if(content.getId() != null && content.getId().equals("cardname") &&
                        content.getContent() != null){
                name = new sun.misc.BASE64Encoder().encode(CryptoUtil.encrypt3DES(content.getContent(), appSecret)) ;
                LOG.info("name=" + name);
                logname = new String(content.getContent());
            }
            if(content.getId() != null && content.getId().equals("cardno") &&
                        content.getContent() != null){
                cardno = new sun.misc.BASE64Encoder().encode(CryptoUtil.encrypt3DES(content.getContent(), appSecret)) ;
                LOG.info("cardno=" + cardno);
                logcardno = new String(content.getContent());
            }
            else if(content.getId() != null && content.getId().equals("photo") &&
                        content.getContent() != null){
                    photo = Base64.encode(content.getContent());
            }
            if(content.getId() != null && content.getId().equals("starttime") &&
                    content.getContent() != null){
                startTime = new sun.misc.BASE64Encoder().encode(CryptoUtil.encrypt3DES(content.getContent(), appSecret)) ;
                LOG.info("startTime=" + startTime);
                logstartTime = new String(content.getContent());
            }
            if(content.getId() != null && content.getId().equals("endtime") &&
                    content.getContent() != null){
                endTime = new sun.misc.BASE64Encoder().encode(CryptoUtil.encrypt3DES(content.getContent(), appSecret)) ;
                LOG.info("endTime=" + endTime);
                logendTime = new String(content.getContent());
            }

        }

        if(name.length() == 0|| cardno.length() == 0 || photo.length() == 0 || startTime.length() == 0 || endTime.length() == 0){
            throw new AuthenticationException("invalid params for idface authentication");
        }
        String postUrl = String.format("http://%s:%s/face-service/v1.0/service/face-four", host, port);
        UUID uuid = UUID.randomUUID();
        String transactionno = uuid.toString().replace("-","");;

        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String clienttime = formatter.format(currentTime);

//        Map<String, Object> params = new HashMap<String, Object>();
//        params.put("app_key", appKey);
//        params.put("client_time", clienttime);
//        params.put("transaction_no", transactionno);
//        params.put("sign", sign);
//        params.put("cardno", cardno);
//        params.put("name", name);
//        params.put("photo", photo);
//
//        GsonBuilder gb = new GsonBuilder();
//        Gson gson = gb.create();


        Map<String,String> obj = new HashMap<String,String> ();
        obj.put("appKey", appKey);
        obj.put("cardno", cardno);
        obj.put("name", name);
        obj.put("beginDate", startTime);
        obj.put("endDate", endTime);
        obj.put("productType", "01");
        obj.put("industrType", "01");
        obj.put("transactionNo", transactionno);
        obj.put("clientTime", clienttime);

        Map<String,String> jsonObject = new HashMap<String,String> ();
        jsonObject.put("appKey", appKey);
        jsonObject.put("cardno", cardno);
        jsonObject.put("name", name);
        jsonObject.put("beginDate", startTime);
        jsonObject.put("endDate", endTime);
        jsonObject.put("productType", "01");
        jsonObject.put("industrType", "01");
        jsonObject.put("transactionNo", transactionno);
        jsonObject.put("clientTime", clienttime);
        String signValue = CryptoUtil.sign(obj,appSecret);

        jsonObject.put("photo", photo);
        jsonObject.put("sign", signValue);

        String jsonStr = new Gson().toJson(jsonObject);
        String response = HttpClientUtil.post(postUrl, jsonStr, "application/json;charset=UTF-8");
        LOG.info("response=" + response);
        JsonObject result = (new JsonParser()).parse(response).getAsJsonObject();
        int code = result.get("code").getAsInt();

        if(code != 0){
            throw new AuthenticationException("IDFace Authentication failed");
        }
        int r = result.get("result").getAsInt();
        if(r != 0){
            throw new AuthenticationException("IDFace Authentication failed");
        }
    }

    @Override
    public void unregister(String userId) throws PluginException {

    }
}
